package com.rfsp.mcp.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rfsp.common.base.ResultVO;
import com.rfsp.common.service.ParamService;
import com.rfsp.common.util.FileUtil;
import com.rfsp.mcp.feign.NHCJssqFeign;
import com.rfsp.common.cache.DictCache;
import com.rfsp.mcp.pojo.dto.FlowDTO;
import com.rfsp.mcp.pojo.dto.MiPayDTO;
import com.rfsp.mcp.pojo.sdto.NhcJssqSDTO;
import com.rfsp.mcp.pojo.vo.NhcJssqResultVO;
import com.rfsp.mcp.pojo.vo.NhcJssqVO;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *江苏宿迁
 */
@Service
public class NhcJssqService {

    @Autowired
    NHCJssqFeign feign;

    @Autowired
    FlowService flowService;

    @Autowired
    DictCache dictCache;

    @Autowired
    ParamService paramService;

    public ResultVO<List<NhcJssqVO>> query(NhcJssqSDTO sdto, String orgCode, String filePath, String fileName){
        Date now=new Date();
        Long sTime=now.getTime();
        String nonce=String.valueOf(sTime);
        String key="sII/rUbOHbbHc6WMCFJBGw==";
        String sign=DigestUtils.md5Hex(sTime + nonce + key);

        URI uri;
        try {
            String url=paramService.getValue("mcp_jssq_ybzfxx_url");
            uri = new URI(url);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return null;
        }
        NhcJssqResultVO result=feign.query(uri,sdto.getIdNo(),sTime,nonce,sign);
        if(!"000000".equals(result.getErrorCode())){
            ResultVO<List<NhcJssqVO>> result1=new ResultVO(result.getErrorCode(),result.getMsg(),null);
            return result1;
        }
        FlowDTO flow=new FlowDTO();
        flow.setInFlag("1");
        flow.setOrgNo(orgCode);
        flow.setEdate(new Date());
        flow.setEtime(new Date());
        flow.setTransCode("JSSQ");
        flow.setStatus("1");
        flow.setPfmId(1l);

        ObjectMapper mapper = new ObjectMapper();
        String content="";
        try {
            content += mapper.writeValueAsString(result);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        content+="\n\n";

        //转化支付信息
        List<NhcJssqVO> voList=new ArrayList<NhcJssqVO>();
        try {
            flow.setStatus("2");
            //data="[{\"ny\": \"202304\",\"idNo\": \"P32130201202\",\"mc\": \"宿迁市宿城区兴扬大药房有限公司\",\"rc\": 266,\"yllb\": \"4101\",\"xzlx\": \"310\",\"totalFee\": 19841.5,\"grzf\": 0,\"jjzf\": 19841.5}]";
            AesUtil aesUtil = new AesUtil(key, null);
            String data=aesUtil.decrypt(result.getData());
            voList =  Arrays.asList(mapper.readValue(data,NhcJssqVO[].class));
            for(NhcJssqVO vo:voList){
                vo.setTotalFee(vo.getTotalFee().setScale(2, BigDecimal.ROUND_HALF_UP));
                vo.setJjzf(vo.getJjzf().setScale(2, BigDecimal.ROUND_HALF_UP));
                vo.setGrzf(vo.getGrzf().setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            try {
                result.setData(data);
                content += mapper.writeValueAsString(result);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            flow.setStatus("4");
        } catch (Exception e) {
            e.printStackTrace();
            flow.setStatus("3");
        }
        flow.setSdate(new Date());
        flow.setStime(new Date());
        flow.setFilePath(filePath+fileName);

        //存储落地文件
        FileUtil.create(filePath,fileName,content,false);
        createFlow(flow);

        ResultVO<List<NhcJssqVO>> result1=new ResultVO(result.getErrorCode(),result.getMsg(),voList);
        return result1;
    }

    public ResultVO<List<NhcJssqVO>> filter(ResultVO<List<NhcJssqVO>> sourceResult,String idNo){
        List<NhcJssqVO> voList=new ArrayList<>();
        List<NhcJssqVO> sourceVoList=sourceResult.getData();

        BigDecimal max=new BigDecimal("999999999999.99");
        String name;
        Pattern pattern;
        Matcher matcher;

        for(NhcJssqVO sourceVo:sourceVoList){
            //年月
            if(sourceVo.getNy()==null || "".equals(sourceVo.getNy())){
                continue;
            }
            if(sourceVo.getNy().length()>6){
                continue;
            }
            if(!sourceVo.getNy().matches("^[0-9]{4}[0]{1}[1-9]{1}$") && !sourceVo.getNy().matches("^[0-9]{4}[1]{1}[0-2]{1}$")){
                continue;
            }


            //定点编号
            if(sourceVo.getIdNo()==null || "".equals(sourceVo.getIdNo())){
                continue;
            }
            if(sourceVo.getIdNo().length()>30){
                continue;
            }
            if(!sourceVo.getIdNo().equals(idNo)){
                continue;
            }
            //定点名称
            if(sourceVo.getMc()==null || "".equals(sourceVo.getMc())){
                continue;
            }
            if(sourceVo.getMc().length()>200){
                continue;
            }

            //人次
            if(sourceVo.getRc()==null){
                continue;
            }
            if(sourceVo.getRc().compareTo(999999)==1){
                continue;
            }

            //医疗类别
            if(sourceVo.getYllb()==null || "".equals(sourceVo.getYllb())){
                continue;
            }
            name=dictCache.DictMap.get("YLLB").get(sourceVo.getYllb());
            if(name==null){
                continue;
            }

            //险种类型
            if(sourceVo.getXzlx()==null || "".equals(sourceVo.getXzlx())){
                continue;
            }
            name=dictCache.DictMap.get("XZLX").get(sourceVo.getXzlx());
            if(name==null){
                continue;
            }

            //总费用
            if(sourceVo.getTotalFee()==null){
                continue;
            }
            if(sourceVo.getTotalFee().compareTo(max)==1){
                continue;
            }

            //个人支付
            if(sourceVo.getGrzf()==null){
                continue;
            }
            if(sourceVo.getGrzf().compareTo(max)==1){
                continue;
            }

            //基金支付
            if(sourceVo.getJjzf()==null){
                continue;
            }
            if(sourceVo.getJjzf().compareTo(max)==1){
                continue;
            }

            voList.add(sourceVo);
        }
        return new ResultVO<List<NhcJssqVO>>(voList);
    }

    private Integer createFlow(FlowDTO dto){
        Integer count=flowService.create(dto);
        return count;
    }

    public List<MiPayDTO> getList(List<NhcJssqVO> sourceList){
        List<MiPayDTO> dtoList=new ArrayList<MiPayDTO>();
        MiPayDTO dto=new MiPayDTO();
        SimpleDateFormat df;
        Long num=1L;
        for(NhcJssqVO source:sourceList){
            dto=new MiPayDTO();
            //dto.setTargetOrgId("");
            dto.setPayNy(source.getNy());
            dto.setPayIdno(source.getIdNo());
            dto.setPayMc(source.getMc());
            dto.setPayRc(source.getRc()+"");
            dto.setPayYllb(source.getYllb());
            dto.setPayXzlx(source.getXzlx());
            dto.setPayTotalfee(source.getTotalFee());
            dto.setPayGrzf(source.getGrzf());
            dto.setPayJjzf(source.getJjzf());
            dto.setNum(num);
            //dto.setPayLogId("");
            dtoList.add(dto);
            num++;
        }
        return dtoList;
    }
    private class AesUtil
    {
        public AesUtil(Key key, String offset) {
            this.key = key;
            this.offset = offset;
        }

        public AesUtil(String key, String offset) {
            this.key = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
            this.offset = offset;
        }

        // 密匙
        protected Key key;
        // 偏移量
        protected String offset;
        // 编码
        protected String encoding = "UTF-8";
        //算法
        protected String algorithm = "AES";
        // 默认的加密算法
        protected String cipherAlgorithm = "AES/ECB/PKCS5Padding";


        public String getEncoding() {
            return encoding;
        }

        public void setEncoding(String encoding) {
            this.encoding = encoding;
        }

        public String getAlgorithm() {
            return algorithm;
        }

        public void setAlgorithm(String algorithm) {
            this.algorithm = algorithm;
        }

        public String getCipherAlgorithm() {
            return cipherAlgorithm;
        }

        public void setCipherAlgorithm(String cipherAlgorithm) {
            this.cipherAlgorithm = cipherAlgorithm;
        }

        /**
         * 解密
         *
         * @param data
         * @return String
         * @throws Exception
         * @author tyg
         * @date 2018年6月28日下午2:50:43
         */
        public String decrypt(String data) throws Exception {
            return decrypt(Base64.getDecoder().decode(data));
        }

        public String decrypt(byte[] data) throws Exception {
            Cipher cipher = Cipher.getInstance(cipherAlgorithm);
            //SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ASCII"), algorithm);
            IvParameterSpec iv = null;
            if (this.cipherAlgorithm.indexOf("ECB") == -1) {
                iv = new IvParameterSpec(offset.getBytes("ASCII"));//使用CBC模式，需要一个向量iv，可增加加密算法的强度
            }
            cipher.init(Cipher.DECRYPT_MODE, key, iv);
            byte[] buffer = data;
            byte[] encrypted = cipher.doFinal(buffer);
            return new String(encrypted, encoding);//此处使用BASE64做转码。
        }
    }
}
